﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using AttributeRouting.Web.Mvc;
using MvcWebRole1.Models;
using TemperatureDatabase;

namespace MvcWebRole1.Controllers
{
    [OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
    public class SensorController : Controller
    {

        [GET("Sensor/GetListForView")]
        public JsonResult GetListForView()
        {
            var temperatureModel = new List<TemperatureModel>();
            using (var db = new TemperatureDBEntities())
            {
                var sensors = db.Sensor.ToList();
                foreach (var sensor in sensors)
                {
                    var measurements = db.Measurement.Where(x => x.SensorId == sensor.Id);
                    double temperature = 0;
                    if (measurements.Any())
                    {
                        temperature = measurements.OrderByDescending(y => y.Timestamp).First().Temperature;
                    }

                    temperatureModel.Add(new TemperatureModel
                    {
                        Id = sensor.Id,
                        Name = sensor.Name,
                        Place = sensor.Place,
                        CurrentTemperature = temperature,
                        TargetTemperature = sensor.Regulator.TargetTemperature,
                        Active = sensor.Regulator.Active
                    });
                }

            }


            return Json(temperatureModel, JsonRequestBehavior.AllowGet);
        }

        [GET("Sensor/Register/{mac}/")]
        public string Register(string mac = "")
        {
            using (var db = new TemperatureDBEntities())
            {
                if (!string.IsNullOrEmpty(mac))
                {
                    var existingSensor = db.Sensor.SingleOrDefault(x => x.Mac == mac);
                    if (existingSensor != null)
                    {
                        return existingSensor.Id.ToString();
                    }
                }
                var timezone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
                var timestamp = TimeZoneInfo.ConvertTime(DateTime.Now, timezone);
                var sensor = new Sensor()
                {
                    Id = 0,
                    Name = "New sensor (" + timestamp.ToShortTimeString().Replace(':',' ') + ")",
                    Place = "New location",
                    Mac = mac
                };


                db.Sensor.Add(sensor);

                var regulator = db.Regulator.Add(new Regulator
                {
                    Sensor = sensor,
                    Active = false,
                    Mac = mac
                });
                db.SaveChanges();
                return sensor.Id.ToString();
            }
        }

        [POST("Sensor/Create/{name}/{place}/")]
        public string Create(string name, string place)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = new Sensor()
                {
                    Id = 0,
                    Name = name,
                    Place = place,
                    Mac = ""
                };
                db.Sensor.Add(sensor);

                db.Regulator.Add(new Regulator
                {
                    Sensor = sensor,
                    Active = false,
                    Mac = ""
                });
                db.SaveChanges();
            }

            return "success";
        }

        [POST("Sensor/{id:int}/SetName/{name}/")]
        public bool SetName(int id, string name)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = db.Sensor.SingleOrDefault(x => x.Id == id);
                if (sensor == null)
                    return false;

                sensor.Name = name;
                db.SaveChanges();
                return true;
            }
        }

        [POST("Sensor/{id:int}/SetPlace/{place}/")]
        public bool SetPlace(int id, string place)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = db.Sensor.SingleOrDefault(x => x.Id == id);
                if (sensor == null)
                    return false;

                sensor.Place = place;
                db.SaveChanges();
                return true;
            }
        }

        [POST("Sensor/{id:int}/Measurement/{temp:double}/")]
        public string Measurement(int id, double temp)
        {
            try
            {
                using (var db = new TemperatureDBEntities())
                {
                    var sensor = db.Sensor.First(x => x.Id == id);
                    var timezone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
                    var timestamp = TimeZoneInfo.ConvertTime(DateTime.Now,timezone);

                    db.Measurement.Add(new Measurement
                    {
                        Sensor = sensor,
                        Timestamp = timestamp,
                        Temperature = temp
                    });
                    db.SaveChanges();

                    if (sensor.Regulator.Active)
                    {
                       return sensor.Regulator.TargetTemperature.ToString();

                    }
                    
                    return "OFF";
                }

            }
            catch (Exception)
            {
                return "OFF";
            }

        }

        [POST("Sensor/{id:int}/Activate/")]
        public bool Activate(int id)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = db.Sensor.SingleOrDefault(x => x.Id == id);
                if (sensor == null || sensor.Regulator == null)
                    return false;
                
                sensor.Regulator.Active = true;
                db.SaveChanges();
            }

            return true;
        }

        [POST("Sensor/{id:int}/Deactivate/")]
        public bool Deactivate(int id)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = db.Sensor.SingleOrDefault(x => x.Id == id);
                if (sensor == null || sensor.Regulator == null)
                    return false;

                sensor.Regulator.Active = false;
                db.SaveChanges();
            }

            return true;
        }

        [POST("Sensor/{id:int}/SetTargetTemperature/{temp:double}/")]
        public bool SetTargetTemperature(int id, double temp)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = db.Sensor.SingleOrDefault(x => x.Id == id);
                if (sensor == null || sensor.Regulator == null)
                    return false;

                
                sensor.Regulator.TargetTemperature = temp;

                db.SaveChanges();
            }

            return true;
        }

        [GET("Sensor/{id:int}/GetTargetTemperature/")]
        public string GetTargetTemperature(int id)
        {
            using (var db = new TemperatureDBEntities())
            {
                var sensor = db.Sensor.SingleOrDefault(x => x.Id == id);
                if (sensor == null || sensor.Regulator == null)
                    return "error";

                return sensor.Regulator.TargetTemperature.ToString();
            }
        }
    }
}
